<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;
use Phinx\Db\Adapter\MysqlAdapter;

final class RemoveGlobalNoticeFromModuleRelationAndField extends AbstractMigration
{
    public function up()
    {
        $globalNoticeSchemaRes = $this->query('select id, code from `schema` where `code` = "global_notice"');
        $globalNoticeSchemaId = 0;
        foreach ($globalNoticeSchemaRes as $item) {
            if ($item['code'] == 'global_notice') {
                $globalNoticeSchemaId = $item['id'];
            }
        }

        $globalNoticeModuleRes = $this->query('select id, code from `module` where `code` = "global_notice"');
        $globalNoticeModuleId = 0;
        foreach ($globalNoticeModuleRes as $item) {
            if ($item['code'] == 'global_notice') {
                $globalNoticeModuleId = $item['id'];
            }
        }

        // 移除水平字段
        $this->execute(
            'delete from field'
            . ' where type = "custom"'
            . ' and module_id = ' . $globalNoticeModuleId);

        // 移除 module_relation 关联
        $this->execute(
            'delete from module_relation'
            . ' where schema_id = ' . $globalNoticeSchemaId);

        // 移除 schema
        $this->execute(
            'delete from `schema`'
            . ' where id = ' . $globalNoticeSchemaId);
    }

    public function down()
    {
        $this->fillRelationData();
        $this->dealCustomFieldTableRelation();
    }


    public function fillRelationData()
    {
        $moduleMap = $this->getAllModuleData();

        // 已经存在的关联模型
        $schemaConfig = [
            [
                'schema' => [
                    'name' => '全局公告模型',
                    'code' => 'global_notice',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 关联公告封面图片
                        'src_module_code' => 'global_notice',
                        'dst_module_code' => 'cos_media',
                        'type' => 'has_one',
                        'link_id' => ['global_notice_cover_img']
                    ],[ // 关联公告附件
                        'src_module_code' => 'global_notice',
                        'dst_module_code' => 'cos_media',
                        'type' => 'has_many',
                        'link_id' => ['global_notice_attachment']
                    ]
                ],
            ],
        ];

        // 写入数据库
        $schemaTable = $this->table('schema');
        $moduleRelationTable = $this->table('module_relation');

        foreach ($schemaConfig as $schemaItem) {
            // 先写入schema
            $schemaItem["schema"]['module_id'] = $moduleMap[$schemaItem["schema"]['code']]['id'];
            $schemaTable->insert($schemaItem["schema"])->save();


            // 获取当前写入schema id
            $query = $this->fetchRow('SELECT max(`id`) as id FROM `schema`');

            foreach ($schemaItem["module_relation"] as $moduleRelationItem) {
                $moduleRelationData = $this->generateNodeConfig($query['id'], $moduleRelationItem, $moduleMap);
                $moduleRelationTable->insert($moduleRelationData)->save();
            }
        }
    }

    /**
     * 获取所有模块数据
     * @return array
     */
    public function getAllModuleData()
    {
        $sql = 'select * from module';
        $result = $this->query($sql);
        $info = array();
        foreach ($result as $key => $val) {
            $info[$val['code']] = $val;
        }
        return $info;
    }

    /**
     * 生成关联节点配置
     * @param $schemaId
     * @param $moduleRelationConfig
     * @param $moduleMap
     * @return array
     * @throws Exception
     */
    public function generateNodeConfig($schemaId, $moduleRelationConfig, $moduleMap)
    {
        $config = [
            'type' => $moduleRelationConfig['type'],
            'src_module_id' => $moduleMap[$moduleRelationConfig['src_module_code']]['id'],
            'dst_module_id' => $moduleMap[$moduleRelationConfig['dst_module_code']]['id'],
            'link_id' => join(',', $moduleRelationConfig['link_id']),
            'schema_id' => $schemaId,
            'uuid' => Webpatser\Uuid\Uuid::generate()->string,
            'node_config' => json_encode([
                "edges" => [
                    "data" => [
                        "type" => "connection",
                        "label" => $moduleRelationConfig['type']
                    ],
                    "source" => $moduleMap[$moduleRelationConfig['src_module_code']]['uuid'],
                    "target" => $moduleMap[$moduleRelationConfig['dst_module_code']]['uuid']
                ],
                "node_data" => [
                    "source" => [
                        "h" => "80px",
                        "w" => "120px",
                        "id" => $moduleMap[$moduleRelationConfig['src_module_code']]['uuid'],
                        "top" => "147px",
                        "left" => "405px",
                        "name" => ucfirst($moduleRelationConfig['src_module_code']),
                        "type" => "module",
                        "icon" => "",
                        "module_id" => $moduleMap[$moduleRelationConfig['src_module_code']]['id'],
                        "module_code" => $moduleRelationConfig['src_module_code'],
                        "module_type" => $moduleMap[$moduleRelationConfig['src_module_code']]['type']
                    ],
                    "target" => [
                        "h" => "80px",
                        "w" => "120px",
                        "id" => $moduleMap[$moduleRelationConfig['dst_module_code']]['uuid'],
                        "top" => "387px",
                        "left" => "229px",
                        "name" => ucfirst($moduleRelationConfig['dst_module_code']),
                        "type" => "module",
                        "icon" => "",
                        "module_id" => $moduleMap[$moduleRelationConfig['dst_module_code']]['id'],
                        "module_code" => $moduleRelationConfig['dst_module_code'],
                        "module_type" => $moduleMap[$moduleRelationConfig['dst_module_code']]['type']
                    ]
                ]
            ])
        ];

        return $config;
    }

    private function dealCustomFieldTableRelation()
    {
        $moduleMap = $this->getAllModuleData();

        $needAddCustomFieldsModuleList = [
            'global_notice' => [
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_cover_img',
                    'relation_module' => 'cos_media',
                    'relation_type' => 'has_one',
                    'default_value' => '',
                    'is_horizontal' => 1
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_attachment',
                    'relation_module' => 'cos_media',
                    'relation_type' => 'has_many',
                    'default_value' => '',
                    'is_horizontal' => 1
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_read_count',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_confirm_count',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_join_users',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => '',
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_join_count',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_reply_count',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_notify_setting',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_plan_switch',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_plan_time',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
                [
                    'table' => 'global_notice',
                    'field_name' => 'global_notice_receive_way',
                    'relation_module' => '',
                    'relation_type' => '',
                    'default_value' => 0,
                    'is_horizontal' => 0
                ],
            ]
        ];

        $rows = [];
        // 处理关联自定义字段
        foreach ($needAddCustomFieldsModuleList as $module => $moduleParam) {
            foreach ($moduleParam as $moduleRelationData) {
                $table = $moduleRelationData['table'];
                $isHorizontal = $moduleRelationData['is_horizontal'] ?? 0;
                $fieldData = [
                    'is_horizontal' => $isHorizontal,
                    'module_id' => $moduleMap[$module]['id'],
                    'type' => 'custom',
                    'table' => $table,
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ];
                $modelName = $this->camelize($table);

                $field = $moduleRelationData['field_name'];
                $defaultValue = $moduleRelationData['default_value'] ?? '';

                if (!empty($moduleRelationData['relation_module']) && !empty($moduleRelationData['relation_type'])) {
                    $dataSource = [ // 数据源
                        "type" => "api", // 数据源类型，fixed 固定 , api 动态
                        "data" => [$moduleRelationData['relation_module']], // 数据源，静态直接配置，动态是一个字符串标识
                        "src_module_id" => $moduleMap[$module]['id'],
                        "dst_module_id" => $moduleMap[$moduleRelationData['relation_module']]['id'],
                        "relation_type" => $moduleRelationData['relation_type']
                    ];
                    $type = 'horizontal_relation';
                } else {
                    $dataSource = [ // 数据源
                        "type" => "fixed", // 数据源类型，fixed 固定 , api 动态
                        "data" => [], // 数据源，静态直接配置，动态是一个字符串标识
                    ];
                    $type = 'string';
                }

                $fieldConfig = $this->generateFieldConfig($modelName, $module, $moduleMap[$module]['id'], $field, $dataSource, $type, $defaultValue);
                $fieldData['config'] = json_encode($fieldConfig);
                $rows[] = $fieldData;
            }
        }
        $this->table('field')->insert($rows)->save();
    }

    /**
     * _ 名称转驼峰
     * @param $unCamelizeWords
     * @param string $separator
     * @return mixed
     */
    public function camelize($unCamelizeWords, $separator = '_')
    {
        $unCamelizeWords = $separator . str_replace($separator, " ", strtolower($unCamelizeWords));
        return str_replace(" ", "", ucwords(ltrim($unCamelizeWords, $separator)));
    }

    /**
     * 生成字段配置
     * @param $modelName
     * @param $realName
     * @param $moduleID
     * @param $field
     * @param $dataSource
     * @param $type
     * @return array
     */
    public function generateFieldConfig($modelName, $realName, $moduleID, $field, $dataSource, $type, $defaultValue = '')
    {
        $fieldConfig = [
            "id" => 0, // 字段id, 固定字段是0，自定义字段是注册的id值
            "field" => $field, // 字段名
            "type" => $type, //字段类型
            "field_type" => "custom", //字段类型 built_in：固定字段，custom：自定义字段
            "disabled" => "no", // 是否禁用（yes, no）
            "require" => 'no', // 是否必须（yes, no）
            "table" => $modelName, // 所属表名
            "module_code" => $realName, // 所属模块名
            "module_id" => $moduleID, // 模块id
            "lang" => strtoupper($field), // 语言包KEY
            "editor" => "select", // 编辑器类型 下拉框
            "edit" => 'allow', // 是否可以编辑（allow, deny）
            "show" => 'yes', // 是否在前台显示 （yes, no）
            "sort" => 'deny', // 是否可以排序（allow, deny）
            "group" => 'deny', // 是否可以分组
            "group_name" => "", // 分组显示名称
            "filter" => 'allow', // 是否可以过滤（allow, deny）
            "multiple" => "no", // 是否可以多选（yes, no）
            "format" => [], // 格式化配置
            "validate" => "", // 验证方法
            "mask" => "", // 掩码配置
            "is_primary_key" => 'no', // 是否是主键（yes, no）
            "is_foreign_key" => 'no', // 是否是外键（yes, no）
            "placeholder" => "no", // 输入框占位文本 （yes, no）
            "show_word_limit" => "no", // 是否显示输入字数统计 （yes, no）
            "autocomplete" => "no", // 是否自动补全 （yes, no）
            "value_icon" => "", // 值图标
            "label_icon" => "", // 文本图标
            "label_width" => 0, // 文本宽度
            "value_width" => 0, //  值宽度
            "is_label" => "no",  //  是否显示文本 （yes, no）
            "default_value" => $defaultValue, // 默认值
            "data_source" => $dataSource
        ];

        return $fieldConfig;
    }
}
